/*将服务器进程守护进程化*/
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/stat.h>
#include<signal.h>
#include<fcntl.h>
#include<unistd.h>
#include"Log.hpp"
#include"Common.hpp"
using namespace LogModule;

const std::string dev = "/dev/null";
void Daemon(int nochdir, int noclose)
{
    //1、忽略掉IO,子进程退出等相关信号
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);

    //2、父进程直接结束(守护进程不能是会话首进程)
    if(fork() > 0)
    {
        exit(0);
    }
    //3、只能说子进程
    setsid(); //成为一个独立会话
    if(nochdir == 0)
      chdir("/");
    
    //4、守护进程依旧可能与显示器、键盘(stdin,stdout, stderr)关联
    //守护进程不从键盘输入，也不需要向显示器打印
    //打开/dev/null，标准输入、标准输出和标准错误重定向到/dev/null
    if(noclose == 0)
    {
        int fd = ::open(dev.c_str(), O_RDWR);//读写方式打开
        if(fd < 0)
        {
            LOG(LogLevel::FATAL) << "open " << dev << "errno";
            exit(OPEN_ERR); 
        }
        else
        {
            dup2(fd, 0);
            dup2(fd, 1);
            dup2(fd, 2);
            close(fd);
        }
    }

}